package socket.nio.demo_01;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;

/**
 * 基于通道的chargen客户端
 */
public class ChargenClient {
    public static int DEFAULT_PORT = 1024;

    public static void main(String[] args) {
        try {
            InetSocketAddress address = new InetSocketAddress("localhost", DEFAULT_PORT);
            SocketChannel client = SocketChannel.open(address);

            /*如果是传统客户端，你可能会获取改socket的输入和输出流。但这不是传统的客户端。利用通道，你可以
            * 直接写入通道本身。不是写入字节数组，而是要写入ByteBuffer对象*/
            ByteBuffer buffer = ByteBuffer.allocate(74);

            // 将OutputStreamSystem.out封装在一个通道中。
            WritableByteChannel output = Channels.newChannel(System.out);

            /*
            * 可以在阻塞和非阻塞模式下运行这个链接，在非阻塞模式下，即使没有任何数据，read()也会立即返回。
            * 这允许程序在试图读取钱做其他操作。它不必等待慢速的网络连接。要改变阻塞模式，可以向configureBlocking()
            * 方法传入true（阻塞）活false(非阻塞)
            */
            /*while(client.read(buffer) != -1) {
                buffer.flip();
                output.write(buffer);
                buffer.clear();
            }*/

            // 下面为非阻塞模式
            client.configureBlocking(false);
            while(true) {
                int n = client.read(buffer);
                if(n > 0) {
                    buffer.flip();
                    //System.out.println(Arrays.toString(buffer.array()));
                    output.write(buffer);
                    buffer.clear();
                } else if(n == -1) {
                    // 这不应该发生，除非服务器发生异常
                    break;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
